package org.springframework.core.type.classreading;

import java.util.Set;

import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.ClassVisitor;
import org.springframework.asm.SpringAsmInfo;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.ServiceClassMetadata;

public abstract class ProxyClassMetadataReadingVisitor extends ClassVisitor implements ServiceClassMetadata, AnnotationMetadata{
	private final ClassLoader classLoader;
	protected final AnnotationMetadataReadingVisitor proxy;
	
	public ProxyClassMetadataReadingVisitor(ClassLoader classLoader) {
		super(SpringAsmInfo.ASM_VERSION);
		this.classLoader = classLoader;
		this.proxy = new AnnotationMetadataReadingVisitor(classLoader);
	}
	
	public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
		proxy.visit(version, access, name, signature, supername, interfaces);
	}

	public void visitOuterClass(String owner, String name, String desc) {
		proxy.visitOuterClass(owner, name, desc);
	}

	public void visitInnerClass(String name, String outerName, String innerName, int access) {
		proxy.visitInnerClass(name, outerName, innerName, access);
	}

	@Override
	public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
		return proxy.visitAnnotation(desc, visible);
	}

	public Set<String> getAnnotationTypes() {
		return proxy.getAnnotationTypes();
	}

	public Set<String> getMetaAnnotationTypes(String annotationType) {
		return proxy.getMetaAnnotationTypes(annotationType);
	}

	public boolean hasAnnotation(String annotationType) {
		return proxy.hasAnnotation(annotationType);
	}

	public boolean hasMetaAnnotation(String metaAnnotationType) {
		return proxy.hasMetaAnnotation(metaAnnotationType);
	}

	public boolean isAnnotated(String annotationType) {
		return proxy.isAnnotated(annotationType);
	}

	public AnnotationAttributes getAnnotationAttributes(String annotationType) {
		return proxy.getAnnotationAttributes(annotationType);
	}

	public AnnotationAttributes getAnnotationAttributes(String annotationType, boolean classValuesAsString) {
		return proxy.getAnnotationAttributes(annotationType, classValuesAsString);
	}

	public boolean hasAnnotatedMethods(String annotationType) {
		return proxy.hasAnnotatedMethods(annotationType);
	}

	public Set<MethodMetadata> getAnnotatedMethods(String annotationType) {
		return proxy.getAnnotatedMethods(annotationType);
	}

	@Override
	public String getClassName() {
		return proxy.getClassName();
	}

	@Override
	public boolean isInterface() {
		return proxy.isInterface();
	}

	@Override
	public boolean isAbstract() {
		return proxy.isAbstract();
	}

	@Override
	public boolean isConcrete() {
		return proxy.isConcrete();
	}

	@Override
	public boolean isFinal() {
		return proxy.isFinal();
	}

	@Override
	public boolean isIndependent() {
		return proxy.isIndependent();
	}

	@Override
	public boolean hasEnclosingClass() {
		return proxy.hasEnclosingClass();
	}

	@Override
	public String getEnclosingClassName() {
		return proxy.getEnclosingClassName();
	}

	@Override
	public boolean hasSuperClass() {
		return proxy.hasSuperClass();
	}

	@Override
	public String getSuperClassName() {
		return proxy.getSuperClassName();
	}

	@Override
	public String[] getInterfaceNames() {
		return proxy.getInterfaceNames();
	}

	@Override
	public String[] getMemberClassNames() {
		return proxy.getMemberClassNames();
	}
	public ClassLoader getClassLoader() {
		return classLoader;
	}
}
